package com.piggy.logi.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.piggy.common.core.enums.CacheKeyEnums;
import com.piggy.common.core.utils.PageUtils;
import com.piggy.common.core.utils.sql.SqlUtil;
import com.piggy.common.core.web.page.PagePlus;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.common.redis.cache.CacheUtils;
import com.piggy.common.satoken.utils.SecurityUtils;
import com.piggy.logi.sys.api.domain.LogiSysDept;
import com.piggy.logi.sys.api.domain.LogiSysRole;
import com.piggy.logi.sys.api.domain.LogiSysUser;
import com.piggy.logi.sys.domain.LogiCustomer;
import com.piggy.logi.sys.domain.LogiWaybill;
import com.piggy.logi.sys.enums.BizNoPrefixEnum;
import com.piggy.logi.sys.service.*;
import com.piggy.logi.sys.vo.LogiKefuIssueExtVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.piggy.logi.sys.bo.LogiKefuIssueQueryBo;
import com.piggy.logi.sys.bo.LogiKefuIssueEditBo;
import com.piggy.logi.sys.domain.LogiKefuIssue;
import com.piggy.logi.sys.mapper.LogiKefuIssueMapper;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 客服问题登记Service业务层处理
 *
 * @author piggy
 * @date 2023-10-25
 */
@Slf4j
@Service
public class LogiKefuIssueServiceImpl extends ServiceImpl<LogiKefuIssueMapper, LogiKefuIssue> implements ILogiKefuIssueService {

    @Resource
    private ILogiCustomerService customerService;

    @Resource
    private ILogiSysUserService userService;

    @Resource
    private ILogiSysDeptService deptService;

    @Resource
    private ILogiWaybillService waybillService;

    @Override
    public LogiKefuIssueExtVo queryById(Long id) {
        return fillData(getVoById(id, LogiKefuIssueExtVo.class));
    }

    @Override
    public TableDataInfo<LogiKefuIssueExtVo> queryPageList(LogiKefuIssueQueryBo bo) {
        bo.setIssueFlag(0L);
        // 查询运单号
        LogiWaybill bill = waybillService.getById(ObjectUtil.defaultIfNull(bo.getWaybillId(),0));
        if (ObjectUtil.isNotEmpty(bill)) {
            bo.setOutCode(bill.getOutCode());
            bo.setWaybillId(null);
        }
        PagePlus<LogiKefuIssue, LogiKefuIssueExtVo> result = pageVo(PageUtils.buildPagePlus(bo, true), buildQueryWrapper(bo), LogiKefuIssueExtVo.class);
        result.setRecordsVo(fillData(result.getRecordsVo()));
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<LogiKefuIssueExtVo> queryList(LogiKefuIssueQueryBo bo) {
        return fillData(listVo(buildQueryWrapper(bo), LogiKefuIssueExtVo.class));
    }

    private List<LogiKefuIssueExtVo.LogiKefuIssueReply> queryReplyList(LogiKefuIssueQueryBo bo) {
        bo.setIssueFlag(1L);
        List<LogiKefuIssue> replies = list(buildQueryWrapper(bo));
        return replies.stream().map(t-> {
            LogiKefuIssueExtVo.LogiKefuIssueReply reply = new LogiKefuIssueExtVo.LogiKefuIssueReply();
            reply.setReplyContent(t.getRemark());
            reply.setReplyUser(t.getCreateBy());
            reply.setReplyDate(t.getCreateTime());
            return reply;
        }).collect(Collectors.toList());
    }

    private LambdaQueryWrapper<LogiKefuIssue> buildQueryWrapper(LogiKefuIssueQueryBo bo) {
        LambdaQueryWrapper<LogiKefuIssue> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, LogiKefuIssue::getId, bo.getId());
        lqw.like(StrUtil.isNotBlank(bo.getIssueCode()), LogiKefuIssue::getIssueCode, bo.getIssueCode());
        lqw.eq(bo.getIssueType() != null, LogiKefuIssue::getIssueType, bo.getIssueType());
        lqw.eq(bo.getWaybillId() != null, LogiKefuIssue::getWaybillId, bo.getWaybillId());
        lqw.like(StrUtil.isNotBlank(bo.getOutCode()), LogiKefuIssue::getOutCode, bo.getOutCode());
        lqw.eq(bo.getIssueDeptId() != null, LogiKefuIssue::getIssueDeptId, bo.getIssueDeptId());
        lqw.eq(bo.getBranchDeptId() != null, LogiKefuIssue::getBranchDeptId, bo.getBranchDeptId());
        lqw.eq(bo.getUserId() != null, LogiKefuIssue::getUserId, bo.getUserId());
        lqw.eq(bo.getCustomerId() != null, LogiKefuIssue::getCustomerId, bo.getCustomerId());
        lqw.like(StrUtil.isNotBlank(bo.getCustomerName()), LogiKefuIssue::getCustomerName, bo.getCustomerName());
        lqw.like(StrUtil.isNotBlank(bo.getScheduleNo()), LogiKefuIssue::getScheduleNo, bo.getScheduleNo());
        lqw.like(StrUtil.isNotBlank(bo.getBusNo()), LogiKefuIssue::getBusNo, bo.getBusNo());
        lqw.eq(bo.getIssueFlag() != null, LogiKefuIssue::getIssueFlag, bo.getIssueFlag());
        lqw.apply(ObjectUtil.isAllNotEmpty(bo.getCreateTimeStart(), bo.getCreateTimeEnd()), "date_format(create_time,'%y%m%d') between date_format({0},'%y%m%d') and date_format({1},'%y%m%d') " , bo.getCreateTimeStart(), bo.getCreateTimeEnd());
        // 部门数据权限过滤
        if (ObjectUtil.isNotNull(bo.getDeptId())) {
            SqlUtil.dataPermissionFilter(lqw, bo.getDeptId());
        }
        return lqw;
    }

    private LogiKefuIssueExtVo fillData(LogiKefuIssueExtVo Any) {

        if (ObjectUtil.isNotEmpty(Any.getUserId())) {
            LogiSysUser user = userService.getById(Any.getUserId());
            if (ObjectUtil.isNotEmpty(user)) {
                Any.setUserName(user.getPhonenumber());
            }
        }

        if (ObjectUtil.isNotEmpty(Any.getCustomerId())) {
            LogiCustomer customer = customerService.getById(Any.getCustomerId());
            if (ObjectUtil.isNotEmpty(customer)) {
                Any.setCustomerName(customer.getCustomerName());
            }
        }

        if (ObjectUtil.isNotEmpty(Any.getBranchDeptId())) {
            LogiSysDept dept = deptService.getById(Any.getBranchDeptId());
            if (ObjectUtil.isNotEmpty(dept)) {
                Any.setBranchDeptName(dept.getDeptName());
            }
        }

        if (ObjectUtil.isNotEmpty(Any.getIssueDeptId())) {
            LogiSysDept dept = deptService.getById(Any.getIssueDeptId());
            if (ObjectUtil.isNotEmpty(dept)) {
                Any.setIssueDeptName(dept.getDeptName());
            }
        }

        /** 查询回复列表 **/
        Any.setReplyList(queryReplyList(new LogiKefuIssueQueryBo().setIssueCode(Any.getIssueCode()).setIssueFlag(1L)));

        return Any;
    }

    private List<LogiKefuIssueExtVo> fillData(List<LogiKefuIssueExtVo> voList) {
        voList.stream().peek(this::fillData).collect(Collectors.toList());
        return voList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LogiKefuIssueExtVo insertByAddBo(LogiKefuIssueEditBo bo) {
        LogiKefuIssue exists = null;
        if (ObjectUtil.isNotEmpty(bo.getId())) {
            exists = getById(bo.getId());
        }
        if (ObjectUtil.isEmpty(exists)) {
            String date = DateUtil.format(new Date(), "yyyyMMdd");
            String key = CacheKeyEnums.LogiIssueNo.getKey(date);
            if (!CacheUtils.hasKey(key)) {
                CacheUtils.cache(0, key, 2L, TimeUnit.DAYS);
            }
            Long no = CacheUtils.incrBy(key);
            bo.setIssueCode(String.format("%s%s%06d", BizNoPrefixEnum.ISSUE_NO.getCode(), date, no));
        }
        if (ObjectUtil.isNotEmpty(exists)) {
            bo.setIssueCode(exists.getIssueCode());
        }
        bo.setId(null);
        LogiKefuIssue add = BeanUtil.toBean(bo, LogiKefuIssue.class);
        add.setDeptId(SecurityUtils.getMainDeptId());
        add.setBranchDeptId(SecurityUtils.getDeptId());
        save(add);
        return queryById(add.getId());
    }

    @Override
    @Transactional
    public LogiKefuIssueExtVo updateByEditBo(LogiKefuIssueEditBo bo) {
        LogiKefuIssue update = BeanUtil.toBean(bo, LogiKefuIssue.class);
        updateById(update);
        return queryById(update.getId());
    }

    @Override
    @Transactional
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }
}
